###################################################
# author: limodou@gmail.com
# license: BSD
###################################################

import re

def wikiparse(text):
    return WikiParser().parse(text)

class WikiParser(object):
    """
    >>> a = '''<p>This is a wiki page
    ... HelpPage <a class="HelpPage" href="http://google.com">http://google.com</a></p>
    ... <h1>HelpPage</h1>
    ... ThisNewPage
    ... [wiki:Help Help page]
    ... '''
    >>> w = WikiParser()
    >>> print w.parse(a)
    <p>This is a wiki page
    <a href="../HelpPage">HelpPage</a> <a class="HelpPage" href="http://google.com">http://google.com</a></p>
    <h1>HelpPage</h1>
    <a href="../ThisNewPage">ThisNewPage</a>
    <a href="../Help">Help page</a>
    <BLANKLINE>
    """
    WIKI_PATTERN = re.compile(r'\[wiki:(?P<wikiname>\w+)\s+(?P<wikititle>.*?)\]|(?P<wiki>(?:[A-Z]+[a-z]+){2,})')
    
    def __init__(self, wiki_pattern=None, 
        exclude=['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'pre', 'a', 'script', 'style', 'tt', 'code']):
        self.exclude = exclude
        if isinstance(wiki_pattern, (str, unicode)):
            wiki_pattern = re.compile(wiki_pattern)
        self.wiki_pattern = wiki_pattern or self.WIKI_PATTERN
        
    def parse(self, text):
        r = re.compile(r'(<.+?>)')
        s = []
        stack = []
        for i in r.split(text):
            if not i:
                continue
            if i.startswith('</'):
                tag = i[2:-1].strip().lower()
                if tag in self.exclude:
                    a = stack.pop()
                    while stack:
                        if a == tag:
                            break
                        else:
                            a = stack.pop()
                s.append(i)
            elif i[0] == '<':
                tag = i[1:-1].strip().lower().split()[0]
                if tag in self.exclude:
                    stack.append(tag)
                s.append(i)
            else:
                if stack:
                    s.append(i)
                else:
                    s.append(self.replace(i))
        return ''.join(s)
                    
    def replace(self, text):
        def sub(m):
            d = m.groupdict()
            if d['wiki']:
                return '<a href="%(wiki)s">%(wiki)s</a>' % d
            else:
                return '<a href="%(wikiname)s">%(wikititle)s</a>' % d
        return self.wiki_pattern.sub(sub, text) 
                
        
if __name__ == '__main__':
    a = '''<div class="document" id="welcome-to-uliweb-wiki">
<h1 class="title">Welcome to Uliweb wiki</h1>
<p>This app is developed by Limodou.</p>
<p>Hope you enjoy it!</p>
<p><a class="reference" href="http://gogle.com">http://gogle.com</a></p>
<pre class="literal-block">
a &gt; b
</pre>
<p>&lt;a href=&quot;<a class="reference" href="http://gogle.com">http://gogle.com</a>&quot;&gt;google.com&lt;/a&gt;</p>
<p>This is HelpPage.</p>
</div>
<script>
a<b
c>d
</script>
'''
    w = WikiParser()
    print w.parse(a)
